﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Autodesk.AutoCAD.Windows;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.ApplicationServices;
using ACADApplication = Autodesk.AutoCAD.ApplicationServices.Application;
using ACADDatabase = Autodesk.AutoCAD.DatabaseServices.Database;
using ACADDocument = Autodesk.AutoCAD.ApplicationServices.Document;

namespace YNCNumberSys
{
    /// <summary>
    /// 根据块中的属性,创建属性引用,并插入块引用.
    /// </summary>
    public class ZJAppendAttribute
    {
        #region 属性
        /// <summary>
        /// 块表记录.
        /// </summary>
        ObjectId _id_BlockTableRecord;
        /// <summary>
        /// 块表记录引用.
        /// </summary>
        ObjectId _id_BlockReference;
        /// <summary>
        /// 事务,为空表示操作当前图纸空间.
        /// </summary>
        private Transaction _trs_Transaction;
        /// <summary>
        /// 图纸文档WorkingDatabase,为空表示当前的图纸空间.
        /// </summary>
        private ACADDatabase _wdb_DataBase;
        /// <summary>
        /// 该值如果为True,则(1)_trs_Transaction,_wdb_DataBase均为当前图纸空间;(2)事务提交在该类内完成.
        /// </summary>
        private bool _b_TransactionIsUsed;
        #endregion

        public ZJAppendAttribute(ACADDatabase wdb_DataBase, Transaction trs_Transaction, 
            ObjectId id_BlockTableRecord, ObjectId id_BlockReference)
        {
            _wdb_DataBase = wdb_DataBase;
            _trs_Transaction = trs_Transaction;
            _id_BlockTableRecord=id_BlockTableRecord;
            _id_BlockReference=id_BlockReference;
            _b_TransactionIsUsed = true;
        }
        public ZJAppendAttribute(
            ObjectId id_BlockTableRecord, ObjectId id_BlockReference)
        {
            _wdb_DataBase = HostApplicationServices.WorkingDatabase;
            _trs_Transaction = null;
            _id_BlockTableRecord = id_BlockTableRecord;
            _id_BlockReference = id_BlockReference;
            _b_TransactionIsUsed = false;
        }
        private void DoAppendAttribute()
        {
            BlockTableRecord blockRecord = (BlockTableRecord)_trs_Transaction.GetObject(_id_BlockTableRecord, OpenMode.ForWrite);
            BlockReference blkRef = (BlockReference)_trs_Transaction.GetObject(_id_BlockReference, OpenMode.ForWrite);
            Matrix3d xformMat = blkRef.BlockTransform;
            foreach (ObjectId id in blockRecord)
            {
                DBObject ent = (DBObject)_trs_Transaction.GetObject(id, OpenMode.ForRead);
                if (ent.GetType().Name == "AttributeDefinition")
                {
                    AttributeDefinition attdef = (AttributeDefinition)ent;
                    AttributeReference attrib = new AttributeReference();
                    attrib.SetPropertiesFrom(attdef);
                    attrib.Invisible = attdef.Invisible;
                    attrib.FieldLength = attdef.FieldLength;
                    attrib.HorizontalMode = attdef.HorizontalMode;
                    attrib.VerticalMode = attdef.VerticalMode;
                    attrib.Position = attdef.Position;
                    if (attrib.HorizontalMode != TextHorizontalMode.TextLeft)
                    {
                        attrib.AlignmentPoint = attdef.AlignmentPoint;
                    }
                    attrib.Rotation = attdef.Rotation;
                    attrib.Height = attdef.Height;
                    //attrib.TextStyle = attdef.TextStyle;
                    attrib.Tag = attdef.Tag;
                    attrib.TextString = "";
                    blkRef.AttributeCollection.AppendAttribute(attrib);
                    attrib.TransformBy(xformMat);
                    attrib.WidthFactor = attdef.WidthFactor;
                    //attdef.Close();
                    //attrib.Close();
                }
            }
        }
        public void Do()
        {
            if (!_b_TransactionIsUsed)
            {
                using (_trs_Transaction = _wdb_DataBase.TransactionManager.StartTransaction())
                {
                    DoAppendAttribute();
                    _trs_Transaction.Commit();
                    _trs_Transaction.Dispose();
                }
            }
            else
            {
                DoAppendAttribute();
            }
        }
    }
}
